From 9ddba6188a1e2f5328b8caacb7328120a78b5e2b Mon Sep 17 00:00:00 2001 From: Aki Tuomi Date: Fri, 12 Jun 2026 11:19:42 +0000 Subject: [PATCH] [PATCH 3/4] lib-compression: istream-zstd - Guard against no-progress loop in read If ZSTD_decompressStream() returns with neither input consumed nor output produced, the read loop would spin indefinitely. Add a check after each call: if input.pos is unchanged and output.pos is zero, treat it as a corrupt stream (EIO). Gbp-Pq: Name 0003-lib-compression-istream-zstd-Guard-against-no-progre.patch --- src/lib-compression/istream-zstd.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/lib-compression/istream-zstd.c b/src/lib-compression/istream-zstd.c index 9e059bc..b5505c8 100644 --- a/src/lib-compression/istream-zstd.c +++ b/src/lib-compression/istream-zstd.c @@ -175,12 +175,20 @@ static ssize_t i_stream_zstd_read(struct istream_private *stream) zstream->output.pos = 0; zstream->output.size = ZSTD_DStreamOutSize(); + size_t old_input_pos = zstream->input.pos; size_t zret = ZSTD_decompressStream(zstream->dstream, &zstream->output, &zstream->input); if (ZSTD_isError(zret) != 0) { i_stream_zstd_read_error(zstream, zret); return -1; } + if (zstream->input.pos == old_input_pos && zstream->output.pos == 0) { + io_stream_set_error(&zstream->istream.iostream, + "zstd.read(%s): decompressor made no progress", + i_stream_get_name(&zstream->istream.istream)); + zstream->istream.istream.stream_errno = EIO; + return -1; + } /* ZSTD magic number is 4 bytes, but it's only defined after v0.8 */ if (!zstream->hdr_read && zstream->input.size > 4) zstream->hdr_read = TRUE; -- 2.39.5